(function ($, tpl) {
    $.fn.dt = function () {
        var url = this.attr('data-action'), $this = this, template = this.find('tbody>tr:first-child'), sort = {}, map = {},
            tbody = this.find('tbody'), thead = this.find('thead'),
            buildPage = function (result) {
                var r = {};
                r.start = result.size * result.number + 1;
                r.end = result.size * result.number + result.numberOfElements;
                r.total = result.totalElements;
                r.current = result.number;
                r.pages = [];
                var start = 0 , end = result.totalPages;
                if (result.totalPages > 5) {
                    start = result.number - 2;
                    start = Math.max(start, 0);
                    end = start + 5;
                    if (end > result.totalPages) {
                        end = result.totalPages;
                        start = end - 5;
                    }
                }
                for (var i = start; i < end; i++) {
                    r.pages.push(i + 1);
                }
                return r;
            },
            loadData = function (url, param) {
                param = param || {};
                $this.mask.show();
                $.getJSON(url, param, function (result) {
                    var re = tpl.render('test', result);
                    tbody.empty();
                    tbody.append(re);
                    var p = $('<div class="row"/>').append(tpl.render('pagination', buildPage(result)));
                    $this.next().remove();
                    $this.after(p);
                    $this.mask.hide();
                })
            };
        $this.url = url;
        $this.mask = $('<div/>', {
            'class': 'dataTables_processing',
            html: '<i class="fa fa-coffee"></i>请稍等...'
        });

        $this.render = function (data, html) {
            var reg;
            for (var k in data) {
                reg = new RegExp('@{' + k + '}', 'ig')
                html = html.replace(reg, data[k]);
            }
            return html;
        }
        $this.pagination = {
            rendered: false,
            infoTemp: '第 @{start} 至 @{end} 条数据，共 @{total} 条',
            render: function (totalPage, totalElements, number, size) {
                var text = this.infoTemp.replace(/@{start}/, size * number);
                text = text.replace(/@{end}/, size * number + size);
                text = text.replace(/@{total}/, totalElements);
                this.info.find('div.dataTables_info').text(text);
                var pageContainer = this.page_wrapper.find('ul.pagination'), start, end;
                pageContainer.empty();
                pageContainer.append($('<li/>', {class: 'Previous', html: '<a href="#"><i class="fa fa-angle-left"></i></a>'}));
                start = 0;
                end = totalPage;
                if (totalPage > 5) {
                    start = number - 2;
                    start = Math.max(start, 0);
                    end = start + 5;
                    if (end > totalPage) {
                        end = totalPage;
                        start = end - 5;
                    }
                }
                for (var i = start; i < end; i++) {
                    var click = function () {
                        loadData($this.url, {page: $(this).text()});
                    };
                    var a = $('<a/>', {
                        href: '#', text: (i + 1), on: {click: click}
                    });
                    var li = $('<li/>');
                    if (i == number) {
                        li.addClass('active');
                    }
                    pageContainer.append(li.append(a));
                }

                pageContainer.append($('<li/>', {class: 'Next', html: '<a href="#"><i class="fa fa-angle-right"></i></a>'}));
                if (number != 0) {
                    pageContainer.find('li.Previous > a').on('click', function () {
                        loadData($this.url, {page: number});
                    });
                }
                if (number != totalPage - 1) {
                    pageContainer.find('li.Next > a').on('click', function () {
                        loadData($this.url, {page: number + 2});
                    });
                }
                if (!this.rendered) {
                    this.container.append(this.info).append(this.page_wrapper);
                    $this.after(this.container);
                    this.rendered = true;
                }
            },
            container: $('<div/>', {class: 'row'}),
            info: $('<div/>', {
                class: 'col-md-5 col-sm-12',
                html: '<div class="dataTables_info"></div>'
            }),
            page_wrapper: $('<div/>', {class: 'col-md-7 col-sm-12'}).append($('<div/>', {
                class: 'dataTables_paginate paging_bootstrap'
            }).append($('<ul/>', {class: 'pagination'})))

        };
        $this.append($this.mask);
        $this.after($this.pagination);
        template.hide();
        template.find('td').each(function (i, e) {
            map[i] = e;
        });
        thead.find('th').each(function (i, v) {
                var $v = $(v);
                if ($v.hasClass('sorting')) {
                    $v.data('sorting', $v.attr('map'));
                    $v.on('click', function () {
                        var sortby = "asc";
                        var classes = $v.attr('class').split(" ");
                        if ($v.hasClass('sorting_asc')) {
                            sortby = "desc";
                        }
                        for (var i in classes) {
                            var clazz = classes[i];
                            if (clazz.match("^sorting")) {
                                $v.removeClass(clazz);
                            }
                        }
                        $v.addClass('sorting_' + sortby);
                        loadData(url, {sortby: $v.data("sorting") + "_" + sortby, page: 1});
                    })
                }
            }
        );
        loadData(url, {page: 1});
    };
    $('table[data-role="dt"]').dt();
}(jQuery, template));